home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / (A)Z / (A)Z8.ADF / Robotroff / functions.c < prev    next >
C/C++ Source or Header  |  1987-03-23  |  8KB  |  370 lines

  1. /* :ts=8 bk=0
  2.  *
  3.  * functions.c:        Functions to do obscene things to mouse pointer.
  4.  *
  5.  * Leo L. Schwab            8703.18        (415)-456-6565
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <intuition/intuition.h>
  10. #include <graphics/sprite.h>
  11. #include <hardware/custom.h>
  12. #include "robotroff.h"
  13.  
  14.  
  15. extern UWORD    hr1[], hr2[], hr3[], hl1[], hl2[], hl3[], hu1[], hu2[], hu3[],
  16.         gr1[], gr2[], gr3[], nforce[],
  17.         hulkcolor[], gruntcolor[], nforcecolor[];
  18.  
  19. extern struct IOStdReq        *ioreq;
  20. extern struct InputEvent    mouse;
  21. extern struct SimpleSprite    spr;
  22. extern struct Preferences    prefs;
  23. extern struct Window        *win;
  24. extern struct Screen        *wbs;
  25. extern long            sprnum;
  26. extern int            wide, high;
  27. extern void            *vp;
  28.  
  29. struct Custom *cstm = 0xdff000;
  30.  
  31. UWORD            *leftseq[] = { hl1, hl2, hl1, hl3 };
  32. UWORD            *rightseq[] = { hr1, hr2, hr1, hr3 };
  33. UWORD            *udseq[] = { hu1, hu2, hu1, hu3 };
  34. UWORD            *gruntseq[] = { gr1, gr2, gr1, gr3 };
  35.  
  36. static int idxsav, dirchange;
  37.  
  38.  
  39. /*
  40.  * This particular piece of code turned out to be gut-wrenchingly messy.
  41.  * But it's the only way I could think of to make it work the way I wanted.
  42.  * If you know of a cleaner algorithm, write it, send it to me, and I'll
  43.  * use it in a revised version of the program.
  44.  */
  45. dohulk ()
  46. {
  47.     register UWORD **sequence;
  48.     register int idx = 0, dx, dy;
  49.     int mx, my, ox, oy, dhx, dhy, x1, y1, x2, y2,  flag = 0;
  50.  
  51.     setcolors (vp, (int) sprnum, hulkcolor);
  52.     startxy (&spr.x, &spr.y);
  53.     if (spr.x == MINX || spr.x == wide)    /*  Determine starting dir  */
  54.         flag = 1;
  55.     spr.height = HULKHEIGHT;
  56.     ChangeSprite (0L, &spr, leftseq[idx]);
  57.     mx = cstm -> clxdat;    /*  Clear collision status  */
  58.  
  59. trackmouse:
  60.     while (1) {
  61.         getmousexy (&mx, &my, HULKHEIGHT);
  62.         dx = mx - spr.x;  dy = my - spr.y;
  63.         dhx = 4 * sgn (dx);  dhy = 2 * sgn (dy);
  64.         if (flag) {
  65.             x1 = x2 = rnd (abs (dx)) * sgn (dx) + spr.x;
  66.             y1 = spr.y;
  67.             y2 = my;
  68.         } else {
  69.             y1 = y2 = rnd (abs (dy)) * sgn (dy) + spr.y;
  70.             x1 = spr.x;
  71.             x2 = mx;
  72.         }
  73.         ox = mx;  oy = my;
  74.  
  75.         if (flag) {
  76.             dx = dhx;  dy = 0;
  77.             if (walkhulkx (spr.x, x1, dhx))
  78.                 break;
  79.             getmousexy (&mx, &my, HULKHEIGHT);
  80.             if (mx != ox || my != oy)
  81.                 continue;
  82.  
  83.             dx = 0;  dy = dhy;
  84.             if (walkhulky (y1, y2, dhy))
  85.                 break;
  86.             getmousexy (&mx, &my, HULKHEIGHT);
  87.             if (mx != ox || my != oy)
  88.                 continue;
  89.  
  90.             dx = dhx;  dy = 0;
  91.             if (walkhulkx (x2, mx, dhx))
  92.                 break;
  93.         } else {
  94.             dx = 0;  dy = dhy;
  95.             if (walkhulky (spr.y, y1, dhy))
  96.                 break;
  97.             getmousexy (&mx, &my, HULKHEIGHT);
  98.             if (mx != ox || my != oy)
  99.                 continue;
  100.  
  101.             dx = dhx;  dy = 0;
  102.             if (walkhulkx (x1, x2, dhx))
  103.                 break;
  104.             getmousexy (&mx, &my, HULKHEIGHT);
  105.             if (mx != ox || my != oy)
  106.                 continue;
  107.  
  108.             dx = 0;  dy = dhy;
  109.             if (walkhulky (y2, my, dhy))
  110.                 break;
  111.         }
  112.         flag = rnd (2);
  113.     }
  114.  
  115.     if (dx)
  116.         sequence = dx>0 ? rightseq : leftseq;
  117.     else
  118.         sequence = udseq;
  119.     idx = idxsav;
  120.     ox = oy = -9999;
  121.     while (1) {
  122.         spr.x += dx;  spr.y += dy;
  123.         idx = ++idx & 3;
  124.         ChangeSprite (0L, &spr, sequence[idx]);
  125.         movemouse (dx, dy);
  126.         mx = collision();
  127.         Delay (6L);
  128.         if (!collision()) {
  129.             idxsav = idx;
  130.             goto trackmouse;
  131.         }
  132.         getmousexy (&mx, &my, HULKHEIGHT);
  133.         if (mx == ox && my == oy)    /*  Mouse at limit  */
  134.             break;
  135.         ox = mx;  oy = my;
  136.     }
  137.  
  138.     /*  Finish walking hulk off screen  */
  139.     while ((int) spr.x < wide && (int) spr.x > MINX &&
  140.            (int) spr.y < high && (int) spr.y > -HULKHEIGHT) {
  141.         spr.x += dx;  spr.y += dy;
  142.         idx = ++idx & 3;
  143.         ChangeSprite (0L, &spr, sequence[idx]);
  144.         Delay (6L);
  145.     }
  146. }
  147.  
  148. dogrunt ()
  149. {
  150.     register int idx = 0;
  151.     int gx, gy, mx, my;
  152.  
  153.     setcolors (vp, (int) sprnum, gruntcolor);
  154.     startxy (&gx, &gy);
  155.     spr.x = gx;  spr.y = gy;  spr.height = GRUNTHEIGHT;
  156.     ChangeSprite (0L, &spr, gruntseq[idx]);
  157.     mx = cstm -> clxdat;    /*  Clear collision status  */
  158.  
  159.     /*  This will keep chasing you around until it gets you :->  */
  160.     while (!collision()) {
  161.         idx = ++idx & 3;
  162.         getmousexy (&mx, &my, GRUNTHEIGHT);
  163.         if (mx != gx)
  164.             gx += mx > gx ? 4 : -4;
  165.         if (my != gy)
  166.             gy += my > gy ? 4 : -4;
  167.         spr.x = gx;  spr.y = gy;
  168.         ChangeSprite (0L, &spr, gruntseq[idx]);
  169.         Delay (rnd (7) + 4L);
  170.     }
  171.  
  172.     flashpointer ();
  173.     MoveSprite (0L, &spr, (long) MINX, 0L);
  174. }
  175.  
  176. enforce ()
  177. {
  178.     register int track, lim, inc;
  179.     int mx, my, ox = -999, oy = -999, ex, ey, dx, dy, flag = 0;
  180.  
  181.     setcolors (vp, (int) sprnum, nforcecolor);
  182.     startxy (&ex, &ey);
  183.     spr.x = ex;  spr.y = ey;  spr.height = NFORCEHEIGHT;
  184.     ChangeSprite (0L, &spr, nforce);
  185.     mx = cstm -> clxdat;    /*  Clear collision bits  */
  186.  
  187.     /*
  188.      * This is a DDA algorithm that attempts to track the mouse pointer
  189.      * in a straight line, no matter where it is.  It keeps tracking
  190.      * until it gets it.
  191.      */
  192.     while (!collision()) {
  193.         getmousexy (&mx, &my, NFORCEHEIGHT);
  194.         if (mx != ox || my != oy) {    /*  Mouse moved  */
  195.             dx = mx - ex;  dy = my - ey;
  196.             if (abs (dx) > abs (dy)) {
  197.                 flag = 1;
  198.                 lim = abs (dx);
  199.                 inc = abs (dy);
  200.             } else {
  201.                 flag = 0;
  202.                 lim = abs (dy);
  203.                 inc = abs (dx);
  204.             }
  205.             track = lim/2;
  206.             ox = mx;  oy = my;
  207.         }
  208.         if (flag) {
  209.             ex += sgn (dx);
  210.             if ((track += inc) > lim) {
  211.                 track -= lim;
  212.                 ey += sgn (dy);
  213.             }
  214.         } else {
  215.             ey += sgn (dy);
  216.             if ((track += inc) > lim) {
  217.                 track -= lim;
  218.                 ex += sgn (dx);
  219.             }
  220.         }
  221.  
  222.         MoveSprite (0L, &spr, (long) ex, (long) ey);
  223.         WaitTOF ();
  224.     }
  225.  
  226.     flashpointer ();
  227.     MoveSprite (0L, &spr, (long) MINX, 0L);
  228. }
  229.  
  230. walkhulkx (startx, endx, dx)
  231. {
  232.     register UWORD **sequence;
  233.     register int x, idx = 0;
  234.  
  235.     if (dirchange)
  236.         idx = idxsav;
  237.     dirchange = 1;
  238.     sequence = dx>0 ? rightseq : leftseq;
  239.  
  240.     for (x=startx; dx>0 ? x<endx : x>endx; x+=dx, idx = ++idx & 3) {
  241.         spr.x = x;
  242.         ChangeSprite (0L, &spr, sequence[idx]);
  243.         Delay (6L);
  244.         if (collision()) {
  245.             idxsav = idx;
  246.             return (1);
  247.         }
  248.     }
  249.     idxsav = idx;
  250.     return (0);
  251. }
  252.  
  253. walkhulky (starty, endy, dy)
  254. {
  255.     register int y, idx = 0;
  256.  
  257.     if (!dirchange)
  258.         idx = idxsav;
  259.     dirchange = 0;
  260.  
  261.     for (y=starty; dy>0 ? y<endy : y>endy; y+=dy, idx = ++idx & 3) {
  262.         spr.y = y;
  263.         ChangeSprite (0L, &spr, udseq[idx]);
  264.         Delay (6L);
  265.         if (collision()) {
  266.             idxsav = idx;
  267.             return (1);
  268.         }
  269.     }
  270.     idxsav = idx;
  271.     return (0);
  272. }
  273.  
  274. startxy (x, y)
  275. register int *x, *y;
  276. {
  277.     if (rnd (2)) {
  278.         *x = rnd (2) ? MINX : wide;
  279.         *y = rnd (200);
  280.     } else {
  281.         *y = rnd (2) ? MINY : high;
  282.         *x = rnd (320);
  283.     }
  284. }
  285.  
  286. getmousexy (x, y, sprheight)
  287. register int *x, *y;
  288. {
  289.     register struct Screen *s = wbs;
  290.  
  291.     *x = (s -> MouseX >> 1) - 8;
  292.     if (s -> ViewPort.Modes & LACE)
  293.         *y = (s -> MouseY >> 1) + s -> TopEdge - sprheight/2;
  294.     else
  295.         *y = s -> MouseY + s -> TopEdge - sprheight/2;
  296. }
  297.  
  298. setcolors (vp, spritenum, clist)
  299. void *vp;
  300. register UWORD *clist;
  301. {
  302.     long r, g, b, colorbase;
  303.     register int i;
  304.  
  305.     colorbase = getcbase (spritenum);
  306.     for (i=1; i<4; i++) {
  307.         r = getr (clist[i]);
  308.         g = getg (clist[i]);
  309.         b = getb (clist[i]);
  310.         SetRGB4 (vp, colorbase + i, r, g, b);
  311.     }
  312. }
  313.  
  314. flashpointer ()
  315. {
  316.     long rs, gs, bs,  dr, dg, db,  rd, gd, bd;
  317.     register int i, n;
  318.  
  319.     rs = gs = bs = 15;
  320.     rd = getr (prefs.color0);
  321.     gd = getg (prefs.color0);
  322.     bd = getb (prefs.color0);
  323.  
  324.     /*  Compute increments  */
  325.     dr = rd - rs;
  326.     dg = gd - gs;
  327.     db = bd - bs;
  328.  
  329.     for (n=15; n>6; n--) {        /*  First flash  */
  330.         for (i=0; i<3; i++)
  331.             SetRGB4 (vp, 17L + i, (long) n, (long) n, (long) n);
  332.         WaitTOF ();
  333.     }
  334.  
  335.     rs <<= 4;  gs <<= 4;  bs <<= 4;
  336.     for (n=0; n<16; n++) {        /*  Fade to background  */
  337.         rs += dr;
  338.         gs += dg;
  339.         bs += db;
  340.         for (i=0; i<3; i++)
  341.             SetRGB4 (vp, 17L + i, rs>>4, gs>>4, bs>>4);
  342.         WaitTOF ();  WaitTOF ();  WaitTOF ();  WaitTOF ();
  343.     }
  344.  
  345.     Delay (150L);
  346.     SetRGB4 (vp, 17L, (long) getr (prefs.color17),    /*  Yuck!  */
  347.               (long) getg (prefs.color17),
  348.               (long) getb (prefs.color17));
  349.     SetRGB4 (vp, 18L, (long) getr (prefs.color18),
  350.               (long) getg (prefs.color18),
  351.               (long) getb (prefs.color18));
  352.     SetRGB4 (vp, 19L, (long) getr (prefs.color19),
  353.               (long) getg (prefs.color19),
  354.               (long) getb (prefs.color19));
  355. }
  356.  
  357. movemouse (dx, dy)
  358. {
  359.     mouse.ie_NextEvent = 0;
  360.     mouse.ie_Class = IECLASS_RAWMOUSE;
  361.     mouse.ie_TimeStamp.tv_secs = mouse.ie_TimeStamp.tv_micro = 0;
  362.     mouse.ie_Code = IECODE_NOBUTTON;
  363.     mouse.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
  364.     mouse.ie_X = prefs.PointerTicks * (dx + dx);
  365.     /*  Is this *really* right?  */
  366.     mouse.ie_Y = prefs.PointerTicks * (dy + dy);
  367.     if (DoIO (ioreq))
  368.         die ("I/O error.");
  369. }
  370.